package com.ewing.extranal.im.service;

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.axis.utils.StringUtils;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.log4j.Logger;

import com.ewing.extranal.im.ImMessageNotReadPool;
import com.ewing.extranal.im.ImMessageWebSocket;
import com.ewing.extranal.im.contant.ImMessageStatus;
import com.ewing.extranal.im.dto.MessageItem;
import com.ewing.utils.DateUtil;

/**
 * 类/接口注释
 * 
 * @author tansonlam
 * @createDate 2016年5月3日
 * 
 */
public class ImMessageStoragerImpl implements ImMessageStorager {
    private static Logger logger = Logger.getLogger(ImMessageWebSocket.class);
    private final static Map<String, List<String>> chatRecordMap = new HashMap<>();
    private final static Map<String, MessageItem> messageMap = new HashMap<>();
    private ImRelationImpl imRelationImpl = new ImRelationImpl();

    @Override
    public MessageItem recordMessage(Long imUserId, Long relImUserId, String message) {
        checkUserId(imUserId, relImUserId);
        return recordSendMessage(imUserId, relImUserId, message);
    }

    private MessageItem recordSendMessage(Long imUserId, Long relImUserId, String message) {
        // 只记录一份消息
        MessageItem chatHistory = new MessageItem();
        chatHistory.setSendImUserId(imUserId);
        chatHistory.setRevImUserId(relImUserId);
        chatHistory.setContent(message);
        chatHistory.setIconUrl("img/person.jpg");
        chatHistory.setTime(DateUtil.format(new Date(), DateUtil.TIME_FORMAT));
        chatHistory.setReadStatus(ImMessageStatus.UNREAD.getValue());
        messageMap.put(chatHistory.getMessageId(), chatHistory);
        // 为对方增加未读消息总数
        ImMessageNotReadPool.addMessageId(relImUserId, chatHistory.getMessageId());
        // 增加发送者聊天记录
        addChatRecord(imRelationImpl.getRelationIdOrCreate(imUserId, relImUserId),
                chatHistory.getMessageId());
        // 增加接收者聊天记录
        addChatRecord(imRelationImpl.getRelationIdOrCreate(relImUserId, imUserId),
                chatHistory.getMessageId());
        return chatHistory;
    }

    private void addChatRecord(String relationId, String messageId) {
        List<String> recordList = chatRecordMap.get(relationId);
        if (recordList == null) {
            recordList = new ArrayList<>();
            chatRecordMap.put(relationId, recordList);
        }
        logger.info("add chatRecordMap relationId:" + relationId + ",messageId:" + messageId);
        recordList.add(messageId);
    }

    @Override
    public Boolean update2Read(Long imUserId, Long relImUserId, String messageId) {
        checkUserId(imUserId, relImUserId);
        ImRelationImpl imRelationImpl = new ImRelationImpl();
        String relationId = imRelationImpl.getRelationIdOrCreate(imUserId, relImUserId);
        MessageItem messageItem = messageMap.get(messageId);
        messageItem.setReadStatus(ImMessageStatus.READ.getValue());
        ImMessageNotReadPool.removeMessageId(imUserId, messageId);
        return true;
    }

    private void checkUserId(Long imUserId, Long relImUserId) {
        if (imUserId.equals(relImUserId))
            throw new IllegalArgumentException("imUserId can not be same to relImUserId");
    }

    @Override
    public List<MessageItem> getChatHistory(Long imUserId, Long relImUserId, String lastMessageId) {
        checkUserId(imUserId, relImUserId);
        ImRelationImpl imRelationImpl = new ImRelationImpl();
        String relationId = imRelationImpl.getRelationIdOrCreate(imUserId, relImUserId);
        logger.info("getChatHistory imUserId:" + imUserId + ",relImUserId:" + relImUserId
                + ",relationId:" + relationId + ",lastMessageId:" + lastMessageId);
        List<String> recordList = chatRecordMap.get(relationId);
        if (recordList == null)
            return new ArrayList<>();
        List<MessageItem> resultList = new ArrayList<MessageItem>();
        for (String messageId : recordList) {
            if (StringUtils.isEmpty(lastMessageId)) {
                resultList.add(getMessageItem(messageId, relImUserId));
            } else {
                if (Long.valueOf(messageId) > Long.valueOf(lastMessageId)) {
                    resultList.add(getMessageItem(messageId, relImUserId));
                }
            }
        }
        return resultList;
    }

    public MessageItem getMessageItem(String messageId, Long relImUserId) {
        MessageItem messageItem = messageMap.get(messageId);
        MessageItem cloneItem = new MessageItem();
        try {
            BeanUtils.copyProperties(cloneItem, messageItem);
        } catch (IllegalAccessException | InvocationTargetException e) {
          logger.error(e.getMessage(), e);
        }
        cloneItem.setMessageTypeByRelImUserId(relImUserId);
        cloneItem.setRelImUserId(relImUserId);
        return cloneItem;
    }
}
